/*
 * Created by JFormDesigner on Fri Aug 24 16:46:04 EDT 2007
 */

package org.timeticker.gui;

import java.util.*;
import org.timeticker.*;
import org.jdesktop.swingx.JXTable;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;

/**
 * Activity list panel
 *
 * @author Ivan Latysh
 * @version 0.1
 * @since 24-Aug-2007 : 16:12:50 AM
 */
public class ActivityListPanel extends JPanel implements TimekeeperActivityListListener {

  /** Parent frame */
  private Frame parentFrame;
  /** Parent dialog */
  private Dialog parentDialog;
  /** Activities table model */
  private ActivityListTableModel activities;

  public ActivityListPanel(JFrame parent) {
    this();
    this.parentFrame = parent;
  }

	public ActivityListPanel(JDialog parent) {
    this();
    this.parentDialog = parent;
  }

  private ActivityListPanel() {
    // attach ourselves to timekeeper
    Timekeeper.getInstance().addListener(this);
    // execute pre-initialization routine
    preInit();
    // JFormDesigner initialization
    initComponents();
    // execute post-initialization routine
    postInit();
  }

  /**
   * Pre initializatio routine
   */
  private void preInit() {
    activities = new ActivityListTableModel(Timekeeper.getInstance().getActivityList());
  }

  /**
   * Post initialization routine
   */
  private void postInit(){
    // set activities table model
    activitiesTable.setColumnControlVisible(true);
    activitiesTable.setHorizontalScrollEnabled(true);
    activitiesTable.setAutoResizeMode(JXTable.AUTO_RESIZE_ALL_COLUMNS);
    activitiesTable.setHorizontalScrollEnabled(true);
    activitiesTable.packAll();

    // add mouse listener
    activitiesTable.addMouseListener(new MouseListener(){
      public void mouseClicked(MouseEvent e) {
        if (e.getButton()==MouseEvent.BUTTON1 && e.getClickCount()>1) {
          // invoke edit action on double click
          editActivity.actionPerformed(null);
        }
      }
      public void mousePressed(MouseEvent e) {
        if (e.getButton()==MouseEvent.BUTTON3) {
          // select the row
          int row = activitiesTable.rowAtPoint(e.getPoint());
          if (row!=-1) activitiesTable.getSelectionModel().setSelectionInterval(row, row);
        }
      }
      public void mouseReleased(MouseEvent e) {}
      public void mouseEntered(MouseEvent e) {}
      public void mouseExited(MouseEvent e) {}
    });

    // set custom Day renderer
    activitiesTable.setDefaultRenderer(Day.class, new DefaultTableCellRenderer.UIResource() {
      final DateFormat formatter = new SimpleDateFormat("EE MMM dd, yyyy");
      public void setValue(Object value) {
        setText((value == null) ? "" : formatter.format(value));
      }
    });
    // set custom Time renderer
    activitiesTable.setDefaultRenderer(Time.class, new DefaultTableCellRenderer.UIResource() {
      final DateFormat formatter = new SimpleDateFormat("HH:mm");
      public void setValue(Object value) {
        setText((value == null) ? "" : formatter.format(value));
      }
    });
    // set custom duration renderer
    activitiesTable.setDefaultRenderer(Duration.class, new DefaultTableCellRenderer.UIResource() {
      final DateFormat formatter = new SimpleDateFormat("HH:mm");
      public void setValue(Object value) {
        if (null!=value) {
          // get duration in seconds
          long d = (Long)value / 1000;
          // calculate minutes and account for rounding mistake
          long minutes = (long)Math.ceil(d / 60) + (d % 60 ==0 ?0 :1);
          // calculate humber of hours
          long hours = (long)Math.floor(minutes / 60);
          // set text
          setText((hours>0 ?hours+"h " :"")+minutes+"m");
        } else {
          setText("");
        }
      }
    });
    // set custom work type renderer
    activitiesTable.setDefaultRenderer(WorkTypeCode.class, new DefaultTableCellRenderer.UIResource() {
      Timekeeper tt = Timekeeper.getInstance();
      public void setValue(Object value) {
        if (null!=value) {
          String text = null;
          // get work type text
          ObjectList workTypeList = tt.getObjectList(Timekeeper.WORK_TYPE_LIST);
          if (null!=workTypeList) {
            WorkType workType = ((WorkType) workTypeList.get((String) value));
            if (null!=workType) text = workType.getTitle();
          }
          // set text
          setText((null!=text ?text :""));
        } else {
          setText("");
        }
      }
    });
    // set custom project renderer
    activitiesTable.setDefaultRenderer(ProjectCode.class, new DefaultTableCellRenderer.UIResource() {
      Timekeeper tt = Timekeeper.getInstance();
      public void setValue(Object value) {
        if (null!=value) {
          String text = null;
          // get work type text
          ObjectList projectList = tt.getObjectList(Timekeeper.PROJECT_LIST);
          if (null!=projectList) {
            Project project = ((Project) projectList.get((String) value));
            if (null!=project) text = project.getTitle();
          }
          // set text
          setText((null!=text ?text :""));
        } else {
          setText("");
        }
      }
    });
  }

  /**
   * Get notified when TimeTicker load new activity list
   *
   * @param activities loaded activities
   */
  public void loadedActivityList(ActivityList activities) {
    this.activities.setActivities(activities);
    // pack all columns
    Runnable runner = new Runnable() {
      public void run() {
        activitiesTable.packAll();
      }
    };
    if (SwingUtilities.isEventDispatchThread()) {
      runner.run();
    } else {
      SwingUtilities.invokeLater(runner);
    }
  }

  /**
   * Get notified when activity list saved
   *
   * @param activities saved activities
   */
  public void savedActivityList(ActivityList activities) {
    //TODO implement visual modified flag that get re-set when activities saved
  }

  private void initComponents() {
		// JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
		// Generated using JFormDesigner Evaluation license - Ivan Latysh
		toolBar = new JToolBar();
		newActivityBtn = new JButton();
		editActivityBtn = new JButton();
		resumeActivityBtn = new JButton();
		finalizeActivityBtn = new JButton();
		deleteActivityBtn = new JButton();
		scrollPane = new JScrollPane();
		activitiesTable = new JXTable(activities);
		activitylistPopupMenu = new JPopupMenu();
		newActivityMenuItem = new JMenuItem();
		editActivityMenuItem = new JMenuItem();
		resumeActivityMenuItem = new JMenuItem();
		FinalizeActivityMenuItem4 = new JMenuItem();
		deleteActivityMenuItem5 = new JMenuItem();
		newActivity = new NewActivityAction();
		editActivity = new EditActivityAction();
		resumeActivity = new ResumeActivityAction();
		finalizeActivity = new FinalizeActivityAction();
		deleteActivity = new DeleteActivityAction();

		//======== this ========

		// JFormDesigner evaluation mark
		setBorder(new javax.swing.border.CompoundBorder(
			new javax.swing.border.TitledBorder(new javax.swing.border.EmptyBorder(0, 0, 0, 0),
				"JFormDesigner Evaluation", javax.swing.border.TitledBorder.CENTER,
				javax.swing.border.TitledBorder.BOTTOM, new java.awt.Font("Dialog", java.awt.Font.BOLD, 12),
				java.awt.Color.red), getBorder())); addPropertyChangeListener(new java.beans.PropertyChangeListener(){public void propertyChange(java.beans.PropertyChangeEvent e){if("border".equals(e.getPropertyName()))throw new RuntimeException();}});

		setLayout(new BorderLayout());

		//======== toolBar ========
		{
			toolBar.setFloatable(false);

			//---- newActivityBtn ----
			newActivityBtn.setAction(newActivity);
			toolBar.add(newActivityBtn);

			//---- editActivityBtn ----
			editActivityBtn.setText("text");
			editActivityBtn.setAction(editActivity);
			toolBar.add(editActivityBtn);

			//---- resumeActivityBtn ----
			resumeActivityBtn.setText("text");
			resumeActivityBtn.setAction(resumeActivity);
			toolBar.add(resumeActivityBtn);

			//---- finalizeActivityBtn ----
			finalizeActivityBtn.setText("text");
			finalizeActivityBtn.setAction(finalizeActivity);
			toolBar.add(finalizeActivityBtn);

			//---- deleteActivityBtn ----
			deleteActivityBtn.setText("text");
			deleteActivityBtn.setAction(deleteActivity);
			toolBar.add(deleteActivityBtn);
		}
		add(toolBar, BorderLayout.NORTH);

		//======== scrollPane ========
		{

			//---- activitiesTable ----
			activitiesTable.setComponentPopupMenu(activitylistPopupMenu);
			scrollPane.setViewportView(activitiesTable);
		}
		add(scrollPane, BorderLayout.CENTER);

		//======== activitylistPopupMenu ========
		{

			//---- newActivityMenuItem ----
			newActivityMenuItem.setText("text");
			newActivityMenuItem.setAction(newActivity);
			activitylistPopupMenu.add(newActivityMenuItem);
			activitylistPopupMenu.addSeparator();

			//---- editActivityMenuItem ----
			editActivityMenuItem.setText("text");
			editActivityMenuItem.setAction(editActivity);
			activitylistPopupMenu.add(editActivityMenuItem);

			//---- resumeActivityMenuItem ----
			resumeActivityMenuItem.setText("text");
			resumeActivityMenuItem.setAction(resumeActivity);
			activitylistPopupMenu.add(resumeActivityMenuItem);

			//---- FinalizeActivityMenuItem4 ----
			FinalizeActivityMenuItem4.setText("text");
			FinalizeActivityMenuItem4.setAction(finalizeActivity);
			activitylistPopupMenu.add(FinalizeActivityMenuItem4);
			activitylistPopupMenu.addSeparator();

			//---- deleteActivityMenuItem5 ----
			deleteActivityMenuItem5.setText("text");
			deleteActivityMenuItem5.setAction(deleteActivity);
			activitylistPopupMenu.add(deleteActivityMenuItem5);
		}
		// JFormDesigner - End of component initialization  //GEN-END:initComponents
	}

	// JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
	// Generated using JFormDesigner Evaluation license - Ivan Latysh
	private JToolBar toolBar;
	private JButton newActivityBtn;
	private JButton editActivityBtn;
	private JButton resumeActivityBtn;
	private JButton finalizeActivityBtn;
	private JButton deleteActivityBtn;
	private JScrollPane scrollPane;
	private JXTable activitiesTable;
	private JPopupMenu activitylistPopupMenu;
	private JMenuItem newActivityMenuItem;
	private JMenuItem editActivityMenuItem;
	private JMenuItem resumeActivityMenuItem;
	private JMenuItem FinalizeActivityMenuItem4;
	private JMenuItem deleteActivityMenuItem5;
	private NewActivityAction newActivity;
	private EditActivityAction editActivity;
	private ResumeActivityAction resumeActivity;
	private FinalizeActivityAction finalizeActivity;
	private DeleteActivityAction deleteActivity;

  // JFormDesigner - End of variables declaration  //GEN-END:variables

	private class NewActivityAction extends AbstractAction {
		private NewActivityAction() {
			// JFormDesigner - Action initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
			// Generated using JFormDesigner Evaluation license - Ivan Latysh
			ResourceBundle bundle = ResourceBundle.getBundle("org.timeticker.timeticker");

			putValue(NAME, bundle.getString("ActivityListPanel.NewActivityAction.Name"));
			// JFormDesigner - End of action initialization  //GEN-END:initComponents
		}

		public void actionPerformed(ActionEvent e) {
      // construct a new activity dialog
      ActivityDialog activityDialog;
      if (null!=parentDialog) {
        activityDialog = new ActivityDialog(parentDialog, null);
      } else {
        activityDialog = new ActivityDialog(parentFrame, null);
      }
      activityDialog.setVisible(true);
      // check dialog result
      if ("save".equals(activityDialog.getAction())) {
        // finalize current activity
        Activity _activity = activities.getActivities().getActivityInProgress();
        if (null!=_activity) _activity.stop();
        // get new activity from dialog
        Activity activity = activityDialog.getActivity();
        // add new activity
        activities.getActivities().add(activity);
      }
      //dispose dialog
      activityDialog.dispose();
		}
	}

	private class EditActivityAction extends AbstractAction {
		private EditActivityAction() {
			// JFormDesigner - Action initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
			// Generated using JFormDesigner Evaluation license - Ivan Latysh
			ResourceBundle bundle = ResourceBundle.getBundle("org.timeticker.timeticker");

			putValue(NAME, bundle.getString("ActivityListPanel.EditActivityAction.Name"));
			// JFormDesigner - End of action initialization  //GEN-END:initComponents
		}

		public void actionPerformed(ActionEvent e) {
      if (activitiesTable.getSelectedRow()!=-1) {
        // get selected activity
        int index = activitiesTable.getSelectedRow();
        Activity activity = activities.getObjectAtRow(index);
        // construct a new activity dialog
        ActivityDialog activityDialog;
        if (null!=parentDialog) {
          activityDialog = new ActivityDialog(parentDialog, activity);
        } else {
          activityDialog = new ActivityDialog(parentFrame, activity);
        }
        activityDialog.setVisible(true);
        // check dialog result
        if ("save".equals(activityDialog.getAction())) {
          // update activity
          activities.getActivities().set(index, activityDialog.getActivity());
        }
        //dispose dialog
        activityDialog.dispose();
      }
		}
	}

	private class DeleteActivityAction extends AbstractAction {
		private DeleteActivityAction() {
			// JFormDesigner - Action initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
			// Generated using JFormDesigner Evaluation license - Ivan Latysh
			ResourceBundle bundle = ResourceBundle.getBundle("org.timeticker.timeticker");

			putValue(NAME, bundle.getString("ActivityListPanel.DeleteActivityAction.Name"));
			// JFormDesigner - End of action initialization  //GEN-END:initComponents
		}

		public void actionPerformed(ActionEvent e) {
      // get selected index
      int selIndex = activitiesTable.getSelectedRow();
      // remove activity
      if (selIndex>=0) activities.getActivities().remove(activities.getObjectAtRow(selIndex));
      // update selection
      if (selIndex>0) {
        activitiesTable.getSelectionModel().setSelectionInterval(selIndex-1, selIndex-1);
      } else {
        activitiesTable.getSelectionModel().setSelectionInterval(selIndex, selIndex);
      }
		}
	}

	private class ResumeActivityAction extends AbstractAction {
		private ResumeActivityAction() {
			// JFormDesigner - Action initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
			// Generated using JFormDesigner Evaluation license - Ivan Latysh
			ResourceBundle bundle = ResourceBundle.getBundle("org.timeticker.timeticker");

			putValue(NAME, bundle.getString("ActivityListPanel.ResumeActivityAction.Name"));
			// JFormDesigner - End of action initialization  //GEN-END:initComponents
		}

		public void actionPerformed(ActionEvent e) {
      // get selected index
      int selIndex = activitiesTable.getSelectedRow();
      // remove activity
      activities.getActivities().start(activities.getObjectAtRow(selIndex));
		}
	}

	private class FinalizeActivityAction extends AbstractAction {
		private FinalizeActivityAction() {
			// JFormDesigner - Action initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
			// Generated using JFormDesigner Evaluation license - Ivan Latysh
			ResourceBundle bundle = ResourceBundle.getBundle("org.timeticker.timeticker");

			putValue(NAME, bundle.getString("ActivityListPanel.FinalizeActivityAction.Name"));
			// JFormDesigner - End of action initialization  //GEN-END:initComponents
		}

		public void actionPerformed(ActionEvent e) {
      // get selected activity
      ActivityList activityList = activities.getActivities();
      Activity inProgress = activityList.getActivityInProgress();
      if (null!=inProgress) activityList.stop(inProgress);
		}
	}
}
